package cn.ad.server.web.spring.service.components.adtraffic2;

import cn.ad.server.web.spring.model.bes.api.BESAPIConnection;
import cn.ad.server.web.spring.model.bes.api.BESAPIRequest;
import cn.ad.server.web.spring.model.bes.api.BESAPIResponse;
import cn.ad.server.web.spring.model.sts.STSAdResponse;
import cn.ad.server.web.spring.service.actions.context.AdContext;
import cn.ad.server.web.spring.service.actions.handler.gdt.server.HttpConnectionManager;
import cn.ad.server.web.utils.JsonUtils;
import cn.ad.server.domain.ad.AdSpaceAdxMap;
import cn.ad.server.domain.ad.AdTemplate;
import cn.ad.server.domain.ad.AdTemplateSpec;
import cn.ad.server.domain.enumration.*;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Created by zooy on 17-2-7.
 */
@Component
public class BESSSPDispatcher extends AbstractGDTDispatcher implements SSPDispatcher {

    private static Logger logger = LoggerFactory.getLogger(BESSSPDispatcher.class);

    private final String requestAddress = "http://adapi.vnet.mobi/API";

    @Resource
    private String serverAddress;

    @Autowired
    private HttpConnectionManager httpConnectionManager;


    @Override
    public STSAdResponse.AdSpace request(AdContext adContext, STSAdResponse.AdSpace adSpace, AdTemplate adTemplate, AdSpaceAdxMap adSpaceAdxMap) {

        //设置转发失败
        adContext.setForwardType(2);
        String json = compositeParam(adContext, adSpaceAdxMap);

        CloseableHttpClient httpClient = httpConnectionManager.getHttpClient();
        HttpPost httpPost = new HttpPost(requestAddress);
        InputStream ins = null;
        try {

            StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题
            stringEntity.setContentEncoding("UTF-8");
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);
            CloseableHttpResponse httpResponse = httpClient.execute(httpPost);

            ins = httpResponse.getEntity().getContent();

            if (HttpStatus.SC_OK == httpResponse.getStatusLine().getStatusCode()) {
                //拼接返回参数
                BESAPIResponse response = JsonUtils.toObject(ins, BESAPIResponse.class);
                List<BESAPIResponse.Ads> adsList = response.getAds();
                if (response.getResultCode() == 0 && !CollectionUtils.isEmpty(adsList)) {


                    STSAdResponse.Creative[] creatives = new STSAdResponse.Creative[adsList.size()];
                    //暂时只支持一个广告返回
                    for (int j = 0; j < adsList.size(); j++) {

                        BESAPIResponse.Ads ads = adsList.get(j);
                        STSAdResponse.Creative creative = new STSAdResponse.Creative();
                        String[] adNoticeUrls = ads.getAdNoticeUrls();
                        String[] impressions = new String[adNoticeUrls.length + 1];
                        int length = impressions.length;
                        for (int i = 0; i < adNoticeUrls.length; i++) {
                            impressions[i] = adNoticeUrls[i];
                        }
                        impressions[length - 1] = compositeLocalImpUrl(adContext);

                        //设置展示检测
                        creative.setImpression(impressions);
                        STSAdResponse.Event event = new STSAdResponse.Event();
                        event.setEventKey(ActionType.LINK_JUMP.getValue());
                        //设置点击地址
                        event.setEventValue(ads.getAdClickUrl());
                        creative.setEvent(new STSAdResponse.Event[]{event});
                        //设置点击监测
                        creative.setClick(new String[]{compositeLocalClickUrl(adContext)});

                        switch (AdFormat.adFormatMap.get(adContext.getAdFormat())) {

                            case BANNER:
                            case TABLE_SCREEN:
                            case OPEN_SCREEN:
                                STSAdResponse.Banner banner = new STSAdResponse.Banner();
                                banner.setWidth(ads.getAdWidth());
                                banner.setHeight(ads.getAdHeight());
                                String imgUrl = ads.getAdImgs()[0];
                                banner.setCreativeUrl(imgUrl);
                                banner.setType(MaterialFormat.JPG.getName());
                                creative.setBanner(banner);
                                break;
                            case VIDEO:
                                break;
                            case AD_NATIVE:
                                //原生读取广告位上面的模版
                                Map<String, String> specMap = new HashMap<>();
                                String specMapString = adSpaceAdxMap.getSpecMap();
                                if (org.apache.commons.lang3.StringUtils.isNotEmpty(specMapString)) {
                                    for (String spec : specMapString.split(",")) {
                                        String[] split = spec.split(":");
                                        specMap.put(split[0], split[1]);
                                    }
                                }
                                List<AdTemplateSpec> adTemplateSpecs = adTemplate.getAdTemplateSpecs();
                                STSAdResponse.AdNative[] adNatives = new STSAdResponse.AdNative[adTemplateSpecs.size()];
                                STSAdResponse.AdNative adNative = null;

                                String[] adImgs = ads.getAdImgs();
                                for (int k = 0; k < adTemplateSpecs.size(); k++) {
                                    AdTemplateSpec adTemplateSpec = adTemplateSpecs.get(k);
                                    adNative = new STSAdResponse.AdNative();
                                    adNative.setTemplateId(adTemplateSpec.getAdTemplateId());
                                    adNative.setIndex(adTemplateSpec.getIndex());
                                    adNative.setIndexValue(adTemplateSpec.getIndexValue());
                                    adNative.setRequiredField(adTemplateSpec.getElementType());
                                    if (adTemplateSpec.getIndexValue().equals("icon")) {
                                        adNative.setRequiredValue(adImgs[0]);
                                    } else if (adTemplateSpec.getIndexValue().startsWith("desc")) {
                                        adNative.setRequiredValue(ads.getAdDesc()[0]);
                                    } else if (adTemplateSpec.getIndexValue().startsWith("title")) {
                                        adNative.setRequiredValue(ads.getAdTitle());
                                    }

                                    //adNative.setRequiredValue((String) WebUtils.invokeGetValue(ads, specMap.get(adTemplateSpec.getIndexValue())));
                                    //暂时写死成jpg，后期可以改成截取url的后缀
                                    if (adTemplateSpec.getElementType() == ElementType.IMAGE.getValue()) {
                                        adNative.setType(MaterialFormat.JPG.getName());
                                    } else if (adTemplateSpec.getElementType() == ElementType.TEXT.getValue()) {
                                        adNative.setType(MaterialFormat.TEXT.getName());
                                    }
                                    adNatives[k] = adNative;
                                }
                                creative.setAdNative(adNatives);
                                break;
                            default:
                                break;
                        }
                        creatives[j] = creative;
                    }

                    adSpace.setCreative(creatives);
                    adContext.setForwardType(1);
                    return adSpace;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String compositeParam(AdContext adContext, AdSpaceAdxMap adSpaceAdxMap) {

        BESAPIRequest besapiRequest = new BESAPIRequest();

        //设置requestId
        String requestId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        adContext.setGuid(requestId);
        besapiRequest.setRequestId(requestId);
        //设置百度的channelId
        besapiRequest.setChannelId(1010);
        besapiRequest.setAppId(101001);
        besapiRequest.setAdId(adSpaceAdxMap.getAdxSpaceId());
        if (adSpaceAdxMap.getWidth() > 0) {
            besapiRequest.setAdSize(adSpaceAdxMap.getWidth() + "*" + adSpaceAdxMap.getHeight());
        } else {
            besapiRequest.setAdSize(adContext.getAdSpaceWidth() + "*" + adContext.getAdSpaceHeight());
        }
        besapiRequest.setAppPackage(adSpaceAdxMap.getPackageName());
        //设置device类型都是phone
        besapiRequest.setDeviceType("phone");
        besapiRequest.setOsType(adSpaceAdxMap.getOs());
        besapiRequest.setOsVersion(adContext.getOsVersion());
        if (StringUtils.isEmpty(adContext.getBrand())) {
            besapiRequest.setVendor(adContext.getModel());
        } else {
            besapiRequest.setVendor(adContext.getBrand());
        }
        besapiRequest.setModel(adContext.getModel());
        if (adContext.getScreenWidth() > 0) {
            besapiRequest.setScreenSize(adContext.getScreenWidth() + "*" + adContext.getScreenHeight());
        } else {
            besapiRequest.setScreenSize("720*1280");
        }

        if (OS.osMap.get(adContext.getOs()) == OS.IOS) {
            besapiRequest.setIdfa(adContext.getIdfaori());
        } else {

            besapiRequest.setImei(adContext.getImeiori());
            //如果androidId没有的时候传imei
            if (StringUtils.isEmpty(adContext.getAnidori())) {
                besapiRequest.setAndroidId(adContext.getImeiori());
            } else {
                besapiRequest.setAndroidId(adContext.getAnidori());
            }
        }

        besapiRequest.setMac(adContext.getMacori());
        besapiRequest.setIpv4(adContext.getIp());
        besapiRequest.setConnectionType(BESAPIConnection.besAPIConnectionMap.get(Connection.connectionMap.get(adContext.getConnType())));
        besapiRequest.setOperatorType(adContext.getMob_ops());
        return JsonUtils.toJson(besapiRequest);
    }

    private String compositeLocalClickUrl(AdContext adContext) {
        String impUrlFormat = serverAddress + "v2/forward/click/ch/10?version=%s&aid=%s&sid=%s&guid=%s";
        return String.format(impUrlFormat, adContext.getVersion(), adContext.getAdSpaceId(), 0, adContext.getGuid());
    }

    private String compositeLocalImpUrl(AdContext adContext) {
        String impUrlFormat = serverAddress + "v2/forward/imp/ch/10?version=%s&aid=%s&sid=%s&guid=%s";
        return String.format(impUrlFormat, adContext.getVersion(), adContext.getAdSpaceId(), 0, adContext.getGuid());
    }

}
